#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QDebug>
#include "tree/treeitem.h"
#include "element/point.h"
#include <QMessageBox>
#include "element/line.h"
#include "element/plane.h"
#include "element/circle.h"
#include "element/cylinder.h"
#include "fitdialog.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->openGLWidget, &CenterWidget::updateGL, [&](QOpenGLShaderProgram &shader){
        //qDebug()<< "update gl";
        // for(int i=0;i<1e8;++i);
        QTreeWidgetItemIterator it(ui->treeWidget);
        while (*it) {
            TreeItem *item = (TreeItem*)(*it);
            // 在这里处理每个项
            //qDebug() << item->text(0);
            if(item->checkState(0)==Qt::Checked)item->Draw(shader);

            ++it; // 移动到下一个项
        }
    });


    connect(ui->treeWidget, &QTreeWidget::itemSelectionChanged, [&](){
        if(ui->treeWidget->selectedItems().empty()) {
            qDebug()<< "没有项目";
            return;
        }
        TreeItem *it = (TreeItem*)ui->treeWidget->selectedItems().last();

        ui->attrText->setText(it->ele->Info());
    });


}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_actionopen_triggered()
{
    QString filePath= QFileDialog::getOpenFileName(this,
                                                   tr("Open File"),  "D:/selfad/alg_and_graph/3DAlgorithm/CBB3DAlgorithm/Fitting/gauss/data", "*.asc");
    if(filePath.isEmpty())return;
    QFileInfo info(filePath);

    qDebug() <<"大小："<< info.size()
            << "后缀名："<< info.suffix()
            << "文件名："<< info.fileName()
            << "文件路径："<< info.filePath();
    TreeItem *item = new TreeItem(ui->treeWidget);
    item->setText(0, info.fileName());
    item->setCheckState(0, Qt::Checked);

    // 加载点云
    ELEMENT::VertexCloud *ele = new ELEMENT::VertexCloud();
    //ele->setParent(item);
    ui->openGLWidget->makeCurrent();
    ele->setCloud(filePath);
    ui->openGLWidget->doneCurrent();
    item->setEle(ele);

    ui->treeWidget->addTopLevelItem(item);

}

// qt 左边有一个qtreewidget, 里面每一项代表一个点云。右边是一个qopenglwidget，将左边打勾的点云渲染到右边

void MainWindow::keyPressEvent(QKeyEvent *event)
{

    qDebug()<< "key down : "<< event->key()<< ", "<< (event->key()==Qt::Key_Control);
    if(event->key()==Qt::Key_Control) {
        ui->treeWidget->setSelectionMode(QAbstractItemView::MultiSelection);
    }else if(event->key()==Qt::Key_Shift){
        ui->treeWidget->setSelectionMode(QAbstractItemView::ContiguousSelection);
    }
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
    if(event->key()==Qt::Key_Control) {
        ui->treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    }else if(event->key()==Qt::Key_Shift){
        ui->treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    }
}

/*
0 "直线"
1 "平面"
2 "圆"
3 "圆柱"
4 "圆锥"
*/
Element *createEle(int type) {
    Element *ele = NULL;
    switch(type) {
    case 0:
        ele = new ELEMENT::Line();
        break;
    case 1:
        ele = new ELEMENT::Plane();
        break;
    case 2:
        ele = new ELEMENT::Circle();
        break;
    case 3:
        ele = new ELEMENT::Cylinder();
        break;
    case 4:
        break;
    default:
        break;
    }

    return ele;
}

void MainWindow::on_actionfit_triggered()
{
    if(ui->treeWidget->selectedItems().empty()) {
        QMessageBox::warning(this, "警告", "请选择一个点云!");
        return;
    }
    FitDialog *fd = new FitDialog(this);
    connect(fd, &FitDialog::select, [&](int ind, const QString &tex){
        qDebug()<< ind<<tex;
        TreeItem *it = (TreeItem*)ui->treeWidget->selectedItems().last();
        qDebug()<<"选择了" << it->text(0);
        qDebug()<<"点云" << it->ele->vertices.size();

        // 添加拟合元素
        Element *ele = createEle(ind);
        if(!ele || !ele->fit(it->ele->vertices)) {
            QMessageBox::warning(this, "警告", "拟合失败，请选择正确类型!");
            delete(ele);
            return;
        }

        ele->loadGL(ui->openGLWidget);

        // 创建树结点
        TreeItem *item = new TreeItem(it);
        item->setText(0, tex);
        item->setCheckState(0, Qt::Checked);
        item->setEle(ele);
        it->addChild(item);
        it->setExpanded(true);
    });

    fd->show();
}


void MainWindow::on_actionresetcenter_triggered()
{
    Eigen::Vector3d center(0,0,0);
    int cnt=0;
    QTreeWidgetItemIterator it(ui->treeWidget);
    for (;*it;++it) {
        TreeItem *item = (TreeItem*)(*it);
        // 在这里处理每个项
        if(item->checkState(0)!=Qt::Checked)continue;
        cnt += item->ele->vertices.size();
        for(auto &p:item->ele->vertices)center+=p;
    }
    if(cnt==0)return;
    center/=cnt;
    ui->openGLWidget->setCenter(center.x(), center.y(), center.z());
}

